1 using System;
2 using UnityEngine;
3
4 namespace UnityStandardAssets.ImageEffects
5 {
6 [ExecuteInEditMode]
7 [AddComponentMenu ("Image Effects/Color Adjustments/Color Correction (Curves, Saturation)")]
8 public class ColorCorrectionCurves : PostEffectsBase
9 {
10 public enum ColorCorrectionMode
11 {
12 Simple = 0,
13 Advanced = 1
14 }
15
16 public AnimationCurve redChannel = new AnimationCurve(new Keyframe(0f,0f), new Keyframe(1f,1f));
17 public AnimationCurve greenChannel = new AnimationCurve(new Keyframe(0f,0f), new Keyframe(1f,1f));
18 public AnimationCurve blueChannel = new AnimationCurve(new Keyframe(0f,0f), new Keyframe(1f,1f));
19
20 public bool useDepthCorrection = false;
21
22 public AnimationCurve zCurve = new AnimationCurve(new Keyframe(0f,0f), new Keyframe(1f,1f));
23 public AnimationCurve depthRedChannel = new AnimationCurve(new Keyframe(0f,0f), new Keyframe(1f,1f));
24 public AnimationCurve depthGreenChannel = new AnimationCurve(new Keyframe(0f,0f), new Keyframe(1f,1f));
25 public AnimationCurve depthBlueChannel = new AnimationCurve(new Keyframe(0f,0f), new Keyframe(1f,1f));
26
27 private Material ccMaterial;
28 private Material ccDepthMaterial;
29 private Material selectiveCcMaterial;
30
31 private Texture2D rgbChannelTex;
32 private Texture2D rgbDepthChannelTex;
33 private Texture2D zCurveTex;
34
35 public float saturation = 1.0f;
36
37 public bool selectiveCc = false;
38
39 public Color selectiveFromColor = Color.white;
40 public Color selectiveToColor = Color.white;
41
42 public ColorCorrectionMode mode;
43
44 public bool updateTextures = true;
45
46 public Shader colorCorrectionCurvesShader = null;
47 public Shader simpleColorCorrectionCurvesShader = null;
48 public Shader colorCorrectionSelectiveShader = null;
49
50 private bool updateTexturesOnStartup = true;
51
52
53 new void Start ()
54 {
55 base.Start ();
56 updateTexturesOnStartup = true;
57 }
58
59 void Awake () { }
60
61
62 public override bool CheckResources ()
63 {
64 CheckSupport (mode == ColorCorrectionMode.Advanced);
65
66 ccMaterial = CheckShaderAndCreateMaterial (simpleColorCorrectionCurvesShader, ccMaterial);
67 ccDepthMaterial = CheckShaderAndCreateMaterial (colorCorrectionCurvesShader, ccDepthMaterial);
68 selectiveCcMaterial = CheckShaderAndCreateMaterial (colorCorrectionSelectiveShader, selectiveCcMaterial);
69
70 if (!rgbChannelTex)
71 rgbChannelTex = new Texture2D (256, 4, TextureFormat.ARGB32, false, true);
72 if (!rgbDepthChannelTex)
73 rgbDepthChannelTex = new Texture2D (256, 4, TextureFormat.ARGB32, false, true);
74 if (!zCurveTex)
75 zCurveTex = new Texture2D (256, 1, TextureFormat.ARGB32, false, true);
76
77 rgbChannelTex.hideFlags = HideFlags.DontSave;
78 rgbDepthChannelTex.hideFlags = HideFlags.DontSave;
79 zCurveTex.hideFlags = HideFlags.DontSave;
80
81 rgbChannelTex.wrapMode = TextureWrapMode.Clamp;
82 rgbDepthChannelTex.wrapMode = TextureWrapMode.Clamp;
83 zCurveTex.wrapMode = TextureWrapMode.Clamp;
84
85 if (!isSupported)
86 ReportAutoDisable ();
87 return isSupported;
88 }
89
90 public void UpdateParameters ()
91 {
92 CheckResources(); // textures might not be created if we're tweaking UI while disabled
93
94 if (redChannel != null && greenChannel != null && blueChannel != null)
95 {
96 for (float i = 0.0f; i <= 1.0f; i += 1.0f / 255.0f)
97 {
98 float rCh = Mathf.Clamp (redChannel.Evaluate(i), 0.0f, 1.0f);
99 float gCh = Mathf.Clamp (greenChannel.Evaluate(i), 0.0f, 1.0f);
100 float bCh = Mathf.Clamp (blueChannel.Evaluate(i), 0.0f, 1.0f);
101
102 rgbChannelTex.SetPixel ((int) Mathf.Floor(i*255.0f), 0, new Color(rCh,rCh,rCh) );
103 rgbChannelTex.SetPixel ((int) Mathf.Floor(i*255.0f), 1, new Color(gCh,gCh,gCh) );
104 rgbChannelTex.SetPixel ((int) Mathf.Floor(i*255.0f), 2, new Color(bCh,bCh,bCh) );
105
106 float zC = Mathf.Clamp (zCurve.Evaluate(i), 0.0f,1.0f);
107
108 zCurveTex.SetPixel ((int) Mathf.Floor(i*255.0f), 0, new Color(zC,zC,zC) );
109
110 rCh = Mathf.Clamp (depthRedChannel.Evaluate(i), 0.0f,1.0f);
111 gCh = Mathf.Clamp (depthGreenChannel.Evaluate(i), 0.0f,1.0f);
112 bCh = Mathf.Clamp (depthBlueChannel.Evaluate(i), 0.0f,1.0f);
113
114 rgbDepthChannelTex.SetPixel ((int) Mathf.Floor(i*255.0f), 0, new Color(rCh,rCh,rCh) );
115 rgbDepthChannelTex.SetPixel ((int) Mathf.Floor(i*255.0f), 1, new Color(gCh,gCh,gCh) );
116 rgbDepthChannelTex.SetPixel ((int) Mathf.Floor(i*255.0f), 2, new Color(bCh,bCh,bCh) );
117 }
118
119 rgbChannelTex.Apply ();
120 rgbDepthChannelTex.Apply ();
121 zCurveTex.Apply ();
122 }
123 }
124
125 void UpdateTextures ()
126 {
127 UpdateParameters ();
128 }
129
130 void OnRenderImage (RenderTexture source, RenderTexture destination)
131 {
132 if (CheckResources()==false)
133 {
134 Graphics.Blit (source, destination);
135 return;
136 }
137
138 if (updateTexturesOnStartup)
139 {
140 UpdateParameters ();
141 updateTexturesOnStartup = false;
142 }
143
144 if (useDepthCorrection)
145 GetComponent<Camera>().depthTextureMode |= DepthTextureMode.Depth;
146
147 RenderTexture renderTarget2Use = destination;
148
149 if (selectiveCc)
150 {
151 renderTarget2Use = RenderTexture.GetTemporary (source.width, source.height);
152 }
153
154 if (useDepthCorrection)
155 {
156 ccDepthMaterial.SetTexture ("_RgbTex", rgbChannelTex);
157 ccDepthMaterial.SetTexture ("_ZCurve", zCurveTex);
158 ccDepthMaterial.SetTexture ("_RgbDepthTex", rgbDepthChannelTex);
159 ccDepthMaterial.SetFloat ("_Saturation", saturation);
160
161 Graphics.Blit (source, renderTarget2Use, ccDepthMaterial);
162 }
163 else
164 {
165 ccMaterial.SetTexture ("_RgbTex", rgbChannelTex);
166 ccMaterial.SetFloat ("_Saturation", saturation);
167
168 Graphics.Blit (source, renderTarget2Use, ccMaterial);
169 }
170
171 if (selectiveCc)
172 {
173 selectiveCcMaterial.SetColor ("selColor", selectiveFromColor);
174 selectiveCcMaterial.SetColor ("targetColor", selectiveToColor);
175 Graphics.Blit (renderTarget2Use, destination, selectiveCcMaterial);
176
177 RenderTexture.ReleaseTemporary (renderTarget2Use);
178 }
179 }
180 }
181 }